Fractuals
Volume Number: 1
Issue Number: 11
Column Tag: Fortran's World
Fractuals in Fortran 2.1
By Chuck Bouldin, Physicist, National Bureau of Standards
A Look at MacFortran 2.1
Last month's issue contained a first look at Macfortran, an implementation of
FORTRAN on the Macintosh. This article is intended to continue that discussiion, and
specifically to look at the new features in the 2.1 release of Macfortran and to begin to
explore the Macfortran interface to the Toolbox routines. This article will describe the
new Toolbox capabilities in the 2.1 release, the extensions and improvements to
FORTRAN in 2.1 and give a couple of short examples which begin to show how
Macfortran interacts with the Macintosh environment. It will discuss the strengths
(and weaknesses) of this implementation of FORTRAN, and show what this language can
accomplish on the Macintosh.
Why Fortran?
One of the first things to determine about any computer language is the class of
problems for which it is best suited. There are lots of languages now available for the
Macintosh; we need to determine where FORTRAN fits into the hierarchy of tools
available for programming the Mac. Please note that this is not intended to continue
the meaningless debate about the 'best' computer language, rather this intended to be a
(reasonably) realistic assesment of FORTRAN as a tool on the Mac.
First of all, there exists a very clear definition of the language. The American
National Standards Institute (ANSI) has published a document which completely defines
the FORTRAN 77 language. Any implementation of the language must meet the standards
defined by ANSI, or it really isn't FORTRAN. In the past, the main problem with
microcomputer implementations of FORTRAN has been that they were incomplete,
including only a part of the ANSI standard. MacFortran is a refreshing break from the
past; it implements the full ANSI definition of the language. Since the language is so
clearly defined, this makes for a remarkable degree of software portability. Code
written in FORTRAN on any other machine, micro or mainframe, ports easily to the
Macintosh. Obviously, Macintosh extensions such as Toolbox calls will not be of much
use on other machines, but the other parts of the code are standard. Details on the
Toolbox interface and porting FORTAN from other machines to the Mac are given later.
Second, MacFortran is the only fully compiled language for the Macintosh other
than C. This means that when an application must run fast, then the high level language
possibilities are C or FORTRAN. In some ways FORTRAN represents a natural upgrade
from Basic when speed is a concern, since Basic was first derived as a subset of
FORTRAN. Basic programmers who find they need faster running programs will
probably find it easier to convert to FORTRAN than to learn C.
Third, if you crunch numbers, this is your language. MacFortran does not use
SANE, the 80 bit software floating point built into the Mac. MacFortran has its own
floating point; 32 bit single precision and 64 bit double precision. This floating point
is fast, easily the fastest available on the Macintosh. Specific benchmarks are given
below.
The language does has limitations, which show up mostly in the ancient lineage of
FORTRAN. The most glaring limitation is the inability to create data types which
correspond to Pascal records or C structures. The closest that MacFortran comes to
this is simple arrays. This means that when dealing with complex data structures, the
programmer, rather than the compiler, is forced to do some of the bookkeeping about
where various data elements are located.
Toolbox Support
Of course the crucial element of a language for the Macintosh is how well it can
interface to the Toolbox routines provided in the Mac ROMS. MacFortran provides
direct access to almost all of the Toolbox routines, including Quickdraw, access to
serial ports, Window and Menu creation, the font manager, the standard file package,
Text edit, use of Desk accesories from inside FORTRAN programs, and more. Missing so
far are access to the control and memory manager. Although not all of the Toolbox is
directly supported from FORTRAN, MacFortran allows calls to assembly language
subroutines which can obviously access any routine.
MacFortran calls Macintosh routines through a single subroutine, TOOLBX. The
first parameter passed to this subroutine is an upper case character string which is
the name of the Mac routine being called. The parameters which follow are the
arguments that the Mac routine needs. TOOLBX is a 'glue' routine which takes care of
putting the arguments onto the stack or into the cpu registers.
There is one main complication in using MacFortran to access Mac Toolbox
routines. As mentioned earlier, FORTRAN does not support data types such as Pascal
records or C structures. Since such data structures are used by many of the Toolbox
routines, how can these routines be supported from MacFortran? The answer is
simple, the data structures are just mapped onto a MacFortran array, and the array is
then passed to TOOLBX, which handles the mapping from array elements onto stack
locations or 68000 registers. With this type of approach, MacFortran can handle all of
the Mac Toolbox with equal facility.
Using MacFortran
The MacFortran system comes with compiler, linker, librarian, and source code
debugger. Apple's Edit and Rmaker programs are also included. The compiler and
debugger have full Mac-style interfaces with pull-down menus and the usual dialogue
boxes for file selection and compiler options. Suprisingly, the linker and librarian
retain Unix type interfaces.
The compiler is organized into 3 overlays: (1) parsing and preliminary
reduction of tokens into object code, (2) resolution of backwards jumps and some final
code generation (3) setting up pointers for a runtime linkage. The overall compilation
speed for large programs is 500-1000 lines/minute. Due to disc overhead swapping
the compiler overlays, small programs (under 100 lines) will seem much slower,
perhaps 50-200 lines/minute.
As mentioned above, the third compiler pass actually sets up pointers for a
runtime link. In a program which does not call previously compiled subroutines this
justs sets a pointer to load the MacFortran runtime library. At runtime, the library
and any other needed subroutines, will be autoloaded when called. At runtime, first the
default disc and then the internal disc are searched for needed subroutines. During
development, this saves having to crank up the linker every time a change is made in
the code. On the down side, subroutines are not locked in memory after they are called
once; they are reloaded at each call. Clearly, you don't want runtime linking for
subroutines which are called more than a few times. Also, the search path can lead to
some confusion. If an application program is executed from the internal drive and the
runtime library is in the external drive, the runtime library is not found, since the
internal drive is now also the default drive. The internal drive is first searched as the
internal drive and then as the default drive, missing the runtime library. [Isn't this a
bug? -Ed.]
Easily the most impressive component of the package is the source code Debugger.
This utility brings up a window of the MacFortran source code being debugged, a
window to display variables and a 5 line MacFortran output window. The source code
can be single stepped, breakpoints can be set and changed, and variables can be
continuously monitored. This is almost like having a FORTRAN interpreter! Getting
code working is very greatly simplified by this debugger.
The linker and librarian are certainly functional, but do not have a Macintosh
type interface. The worst part of this is having to remember file names. On the plus
side, the linker supports creation of 'scripts', files which contain canned linker
'programs'. This simplifies linking since many of the same libraries and subroutines
are linked to different programs. According to Absoft there are two reasons for the
non-Mac interface: (1) to provide the large table space that the linker needs and still
fit into a 128K machine it was necessary to use a primitive interface, and (2) the
interface remained unchanged in 2.1 since the programming effort was put into
changing the linker to support linking on an entry point, rather than a filename basis.
In 2.0, the ENTRY statement in FORTRAN was effectively disenfranchised since linking
was done on only a filename basis. I still don't like the user interface, but the
functionality of supporting the ENTRY statement is certainly more important. [In
otherwords, the linker isn't finished yet! -Ed.]
The linker also makes no discrimination about what parts of the runtime library
are actually used by a program; the entire library is linked in regardless. This means
that the smallest MacFortran program will be about 18K, a real detriment to writing
desk accessories in this language. On the other hand, several programs can be
completely linked except for the runtime libary and share a single copy of the runtime
library through runtime linking. Also, applications that do anything more involved
than "hello, world" are likely to bring in large fractions of the Runtime library
anyway. Runtime linking is certainly not required. The linker and librarian manage
pre-compiled object code and standalone applications are easily created.
Portability Considerations
As mentioned earlier, one of the main attractions of FORTRAN is the portability of
the language. I have ported several large applications down from a VAX 11/780 and
have learned some of the pitfalls to watch out for when porting code down to the Mac.
Since the use of existing code, particularly mathematical software, is a major
incentive for using Macfortran, it is worth describing the portability considerations
in detail. All of the non-portable code that I have downloaded to the Mac has turned out
to be due to the use of non-standard features in VAX FORTRAN.
First, it is essential to use the SAVE statement in order to preserve variables
between calls to a subroutine. This was mentioned in last months column, but the
impression was given that this is a quirk of Macfortran. It is not. It is standard
FORTRAN, although VAX and most mainframes do not require it. On a small machine
such as the Macintosh, the use of the SAVE statement allows you to write larger
programs by disposing of unneeded variable space. The main caution is that COMMON
blocks must be SAVE-d between calls to a subroutine. This is conterintuitive, but it is
standard FORTRAN.
Second, DATA statements must follow all declarations (REAL, COMPLEX, etc.).
Again, this is standard FORTRAN, but is relaxed on most large machines. The main
place to look out for this is when using INCLUDE statements to enter the COMMON
variables in a group of subroutines that share COMMON blocks.
Third, watch out for READ/WRITE statements that use system dependent logical